package org.onion.pattern.kit.common.jackson.serializer;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * 时间反序列化-取当前值
 * 支持： 时间戳及各种格式的时间类型
 */
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    public static final DateTimeFormatter fmt_yyyy_MM_dd_HH_mm_ss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter fmt_yyyy_MM_dd_HH_mm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    public static final DateTimeFormatter fmt_yyyy_MM_dd_HH = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
    public static final DateTimeFormatter fmt_yyyy_MM_dd = DateTimeFormatter.ofPattern("yyyy-MM-dd");


    @Override
    public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

        if (ObjectUtils.isEmpty(jsonParser)) {
            return null;
        }

        String json = jsonParser.getText();

        return parse(json);
    }


    public static LocalDateTime parse(String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }

        //如果是数字
        if (StringUtils.isNumericSpace(json)) {
            return LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(json)), ZoneId.systemDefault());
        }

        try {
            return LocalDateTime.parse(json, LocalDateTimeDeserializer.fmt_yyyy_MM_dd_HH_mm_ss);
        } catch (Exception e) {
            //
        }

        try {
            LocalDate parse = LocalDate.parse(json, LocalDateTimeDeserializer.fmt_yyyy_MM_dd);
            return parse.atTime(LocalTime.now());
        } catch (Exception e) {
            //
        }

        try {
            return LocalDateTime.parse(json, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        } catch (Exception e) {
            //
        }

        try {
            LocalTime now = LocalTime.now();
            LocalDateTime parse = LocalDateTime.parse(json, LocalDateTimeDeserializer.fmt_yyyy_MM_dd_HH_mm);
            return LocalDateTime.of(parse.getYear(), parse.getMonthValue(), parse.getDayOfMonth(), parse.getHour(), parse.getMinute(), now.getSecond());
        } catch (Exception e) {
            //
        }

        try {
            LocalDate parse = LocalDate.parse(json + "-01", LocalDateTimeDeserializer.fmt_yyyy_MM_dd);
            LocalDateTime localDateTime = parse.atTime(LocalTime.now());
            localDateTime = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
            return localDateTime;
        } catch (Exception e) {
            //
        }

        try {
            LocalTime now = LocalTime.now();
            LocalDateTime parse = LocalDateTime.parse(json, LocalDateTimeDeserializer.fmt_yyyy_MM_dd_HH);
            return LocalDateTime.of(parse.getYear(), parse.getMonthValue(), parse.getDayOfMonth(), parse.getHour(), now.getMinute(), now.getSecond());
        } catch (Exception e) {
            throw new IllegalArgumentException("日期解析失败 " + json);
        }

    }

}
